package com.base.keyvalue.store.impl.filehashmap;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import com.base.keyvalue.store.Storage;
import com.base.keyvalue.utils.RuntimeExceptionWraper;

/**
 * @author yanjiaqiang
 * @date 2011-3-21
 * @version $Id: FileHashMapStorage.java 7 2011-07-15 04:24:04Z JiaqiangYan@gmail.com $
 */
public class FileHashMapStorage implements Storage {

	FileHashMap<String, byte[]> map;
	ReadWriteLock rwLock = new ReentrantReadWriteLock();
	Lock readLock = rwLock.readLock();
	Lock writeLock = rwLock.writeLock();

	public FileHashMapStorage(String pathPrefix, int flags) throws FileNotFoundException, ClassNotFoundException,
			IOException {
		this.map = new FileHashMap<String, byte[]>(pathPrefix, flags);
	}

	public FileHashMapStorage(String tempFilePrefix) throws IOException {
		this.map = new FileHashMap<String, byte[]>(tempFilePrefix);
	}

	@Override
	public int size() {
		readLock.lock();
		try {
			return map.size();
		} finally {
			readLock.unlock();
		}
	}

	@Override
	public boolean isEmpty() {
		readLock.lock();
		try {
			return map.isEmpty();
		} finally {
			readLock.unlock();
		}
	}

	@Override
	public boolean containsKey(Object key) {
		readLock.lock();
		try {
			return map.containsKey(key);
		} finally {
			readLock.unlock();
		}
	}

	@Override
	public boolean containsValue(Object value) {
		readLock.lock();
		try {
			return map.containsValue(value);
		} finally {
			readLock.unlock();
		}
	}

	@Override
	public byte[] get(Object key) {
		readLock.lock();
		try {
			return map.get(key);
		} finally {
			readLock.unlock();
		}
	}

	@Override
	public byte[] put(String key, byte[] value) {
		writeLock.lock();
		try {
			return map.put(key, value);
		} finally {
			writeLock.unlock();
		}
	}

	@Override
	public byte[] remove(Object key) {
		writeLock.lock();
		try {
			return map.remove(key);
		} finally {
			writeLock.unlock();
		}
	}

	@Override
	public void putAll(Map<? extends String, ? extends byte[]> m) {
		writeLock.lock();
		try {
			map.putAll(m);
		} finally {
			writeLock.unlock();
		}
	}

	@Override
	public void clear() {
		writeLock.lock();
		try {
			map.clear();
		} finally {
			writeLock.unlock();
		}
	}

	@Override
	public Set<String> keySet() {
		readLock.lock();
		try {
			return map.keySet();
		} finally {
			readLock.unlock();
		}
	}

	@Override
	public Collection<byte[]> values() {
		readLock.lock();
		try {
			return map.values();
		} finally {
			readLock.unlock();
		}
	}

	@Override
	public Set<Entry<String, byte[]>> entrySet() {
		readLock.lock();
		try {
			return entrySet();
		} finally {
			readLock.unlock();
		}
	}

	@Override
	public byte[] putIfAbent(String k, byte[] v) {
		writeLock.lock();
		try {
			if (!containsKey(k)) {
				return put(k, v);
			}
			return null;
		} finally {
			writeLock.unlock();
		}

	}

	@Override
	public void close() {
		try {
			map.close();
		} catch (Exception e) {
			RuntimeExceptionWraper.wrap(e);
		}
	}

}
